#pragma once

#include <iostream>
#include <memory>
#include <string>

namespace Event
{

using ListState = enum
{
    EVENT_LIST_SUCCESS = 0,
    EVENT_LIST_TYPE_ERROR = 1,
    EVENT_LIST_IMCOMPLETE_ERROR = 2,
    EVENT_LIST_PARSER_ERROR = 3,
    //
    EVENT_LIST_RELOAD = 10,
    EVENT_LIST_END_OF_DATA = 11,
};

using Type = enum EventType
{
    EVENT_TYPE_NONE = 0,
    /* 基本数据类型 */
    EVENT_TYPE_INT8 = 1,
    EVENT_TYPE_UINT8 = 2,
    EVENT_TYPE_INT16 = 3,
    EVENT_TYPE_UINT16 = 4,
    EVENT_TYPE_INT32 = 5,
    EVENT_TYPE_UINT32 = 6,
    EVENT_TYPE_INT64 = 7,
    EVENT_TYPE_UINT64 = 8,
    EVENT_TYPE_FLOAT32 = 9,
    EVENT_TYPE_FLOAT64 = 10,
    EVENT_TYPE_POINTER = 11,
    /* 组合数据类型 */
    EVENT_TYPE_STRING = 21,
    EVENT_TYPE_RAW_STRUCT = 22,
    EVENT_TYPE_RAW_DATA = 23,
    /* List 类型 */
    EVENT_TYPE_LIST = 31,

    /* 结束标志 */
    EVENT_TYPE_END = 'L',
};

using TCollect = union
{
    uint8_t u8;
    int8_t  i8;
    uint16_t u16;
    int16_t  i16;
    uint32_t u32;
    int32_t  i32;
    uint64_t u64;
    int64_t  i64;
    float    f32;
    double   f64;
    void *ptr;
    std::string *str;
    List *lst;
};

class List
{
public:
    List();
    /**
     * @brief 从原始数据中构造 List 结构 (反序列化)
     * @throws 
     */
    List(const char *raw);
    ~List();

    //List(Type, TCollect);
    /* Get current node type */
    Type get_type();

    /* Get current node data */
    const TCollect get_data();

    /* Iterator */
    void iteration_reset();
    List *iteration_get();

    /* Add Data Functions */
    void add_data(bool _data);
    void add_data(unsigned char _data);
    void add_data(char _data);
    void add_data(unsigned short _data);
    void add_data(short _data);
    void add_data(unsigned int _data);
    void add_data(int _data);
    void add_data(unsigned long _data);
    void add_data(long _data);
    void add_data(float _data);
    void add_data(double _data);
    void add_data(void *_data);
    /* 将会接管 std::string 的所有权，该 _data 必须是动态分配的 */
    void add_data(std::string *_data);
    void add_data(List *_data);
    void add_data(const char *_data);

private:
    static ListState complete_check_end(const char *raw);
    static ListState complete_check_type(const char *raw);
    static ListState base_data_pull(const char **p, List **head);

private:
    uint32_t list_num;
    uint32_t data_size;
    List *end;
    List *next;
    List *iter;

    /* 值类型对应系统 */
    Type  type;
    TCollect data;
};

} // namespace Event

